package innerClass;

/**
 * @ProjectName random_code
 * @PackageName innerClass
 * @ClassName demo1
 * @Description:
 * @author: Administrator
 * @Date: 2019/8/20 14:45
 * @Version 1.0
 */
public class demo1 {
    //定义类的作用就是定义变量、创建实例和作为父类被继承
    //定义在其他类内部的类成为内部类（或嵌套类）,包含内部类的类也被成为外部类（或宿主类）
    //1.内部类提供了更好的封装，可以把内部类隐藏在外部类之内，不允许同一个包中的其他类访问该类
    //2.内部类成员可以直接访问外部类的私有数据，因为内部类被当成其外部类成员，同一个类的成员之间可以互相访问，但外部类不能访问内部类的实现细节，例如内部类的成员变量
    //**3.匿名内部类适合用于创建那些仅需要一次使用的类**
    //4、内部类可卡因使用三个修饰符：private、protected、static，外部类不可以使用这三个修饰符
    //5.非静态内部类不能拥有静态成员
    //只要把一个类置于另一个类内部即是内部类，即使是在方法内
    //分类 1.成员内部类（属于类成员，有静态内部类和非静态内部类），2.局部内部类（方法中定义内部类，该类仅在该方法里有效），3.匿名内部类
    //注：内部类与一个源文件中有两个并列的类不同，后者依然是两个类，但是一个源文件中只能有一个public类
    //在编译时内部类也会在同路径下被单独编译为一个类文件即 demo1$CowLeg.class表明是demo1的内部类
    //当外部类，内部类，内部类方法有同名的属性时，使用OuterClass.this.propName,this.propName,propName来分别访问
    //静态成员不能直接访问非静态成员（可以通过创建对象来访问），非静态内部类里也无法定义静态成员
    //static 关键字的作用是把类的成员变成类相关，外部类的上一级程序单元是包，所以不可使用static修饰，而内部类的上一级程序单元是外部类，使用static修饰可以将内部类变成外部类相关，而不是外部类实例相关。
    //非静态内部类的对象必须寄生在外部类的对象里，因此在创建非静态内部类对象之前，必须先创建其外部类对象。

    private double weight;
    //外部类的两个重载的构造器
    public demo1(){}
    public demo1(double weight){this.weight = weight;}

    //定义一个非静态内部类
    //提供了更好的封装，不允许包中的其他类访问该类，private使外部类无法访问内部类的实现细节
    private class CowLeg{
        //非静态内部类的两个实例变量
        private double length;
        private String color;
        //非静态内部类两个重载的构造器
        public CowLeg(){}
        public CowLeg(double length,String color){
            this.length = length;
            this.color = color;
        }

        //非静态内部类的实例方法
        public void info(){
            System.out.println("当前牛腿的颜色是"+color+",高:"+length);
            //直接访问外部类的private修饰的成员变量
            System.out.println("本牛腿所在的奶牛重:"+weight);
        }
    }

    public void test(){
        //有空的构造方法才可以实例化
        CowLeg c1= new CowLeg(1.12,"黑白相同");
        c1.info();
    }

    public static void main(String[] args){
        //静态方法访问本类的非静态方法需要实例化
        demo1 cow = new demo1(378.9);
        cow.test();
    }
}
